package cn.zooz.admin.config.shiro.filter;

import cn.zooz.common.util.kit.HttpUtils;
import lombok.Data;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Bradish7Y on 2017/9/15.
 * 控制同一用户在线session数
 * 参考：https://my.oschina.net/qixiaobo025/blog/906698
 */
@Data
public class KickoutSessionControlFilter extends AccessControlFilter {

    public static final String SESSION_KEY_KICKOUT = "kickout";

    private String kickOutUrl;//成功踢出后重定向url
    private boolean enable;

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (!enable) {
            return true;
        }

        Subject subject = getSubject(request, response);
        Session session;
        String username;
        try {
            username = (String) subject.getPrincipal();
            session = subject.getSession();
            if (!subject.isAuthenticated() && !subject.isRemembered()) {
                //如果没有登录，直接进行之后的流程
                return true;
            }
        } catch (SessionException ex) {
            return true;
        }
        if (username == null || session == null) {
            return true;
        }

        if (session.getAttribute(SESSION_KEY_KICKOUT) != null) {
            try {
                subject.logout();//退出登录
            } catch (Exception e) { //ignore
            }

            saveRequest(request);

            HttpServletRequest httpRequest = WebUtils.toHttp(request);
            if (HttpUtils.isAjax(httpRequest)) {//ajax request
                HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
                httpServletResponse.sendError(401);
                return false;
            } else {
                WebUtils.issueRedirect(request, response, kickOutUrl);//redirect
                return false;
            }
        }

        return true;
    }


}
